package com.alili_tv.system.service.impl;

import com.alili_tv.system.entity.Follow;
import com.alili_tv.system.entity.User;
import com.alili_tv.system.exception.BusinessException;
import com.alili_tv.system.exception.SystemException;
import com.alili_tv.system.mapper.UserMapper;
import com.alili_tv.system.service.FollowService;
import com.alili_tv.system.service.UserService;
import com.alili_tv.system.utils.CommonUtils;
import com.alili_tv.system.utils.ValidUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author baomidou
 * @since 2023-03-17
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private ValidUtils validUtils;

    @Resource
    private FollowService followService;

    @Override
    public User loginWithCode(User user) {
        //
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();

        // 判断是用手机号还是邮箱验证
        if (ValidUtils.isValidPhone(user.getAccount())) {
            user.setPhone(user.getAccount());
            // where phone = #{account}
            queryWrapper.eq(User::getPhone, user.getAccount());
        } else if (ValidUtils.isValidEmail(user.getAccount())) {
            user.setEmail(user.getAccount());
            // where email = #{account}
            queryWrapper.eq(User::getEmail, user.getAccount());
        } else {
            throw new SystemException("手机号或邮箱错误");
        }

        // 从缓存中匹配验证是否正确
        if (!validUtils.validCode(user.getAccount(), user.getCode(), true)) {
            // 验证不通过
            throw new BusinessException("验证码无效");
        }
        // 匹配成功

        // 查询是否存在该用户，不存在则直接创建
        User userInfo = this.getOne(queryWrapper);
        if (userInfo == null) {
            // 用户不存在
            user.setDynamic(LocalDateTime.now());
            user.setMessage(LocalDateTime.now());
            // insert into user (email) value(#{email})
            this.save(user);
            // 初始化用户名
            // update user set name = #{name} where id = #{id}
            LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper
                    .set(User::getName, "ali_" + user.getId())
                    .eq(User::getId, user.getId());
            this.update(updateWrapper);
            // 直接返回新用户数据
            return user;
        } else {
            return userInfo;
        }
    }

    @Override
    public User loginWithPwd(User user) {
        if (user.getPassword() == null || "".equals(user.getPassword()))
            throw new BusinessException("密码不能为空");

        // 密码加密处理 md5
        String pwd = CommonUtils.md5Encryption(user.getPassword());

        // 条件构建器
        // where password = #{pwd}
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPassword, pwd);

        // 判断是用手机号还是邮箱验证，同时添加条件
        if (ValidUtils.isValidPhone(user.getAccount())) {
            queryWrapper.eq(User::getPhone, user.getAccount());
        } else if (ValidUtils.isValidEmail(user.getAccount())) {
            queryWrapper.eq(User::getEmail, user.getAccount());
        } else {
            throw new BusinessException("无效账号");
        }

        // 查询
        // select * from user where phone = #{phone} and password = #{password}
        User one = this.getOne(queryWrapper);
        if (one == null)
            throw new BusinessException("账号或密码错误");

        return one;
    }

    @Override
    public String getNameById(Long id) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .select(User::getName)
                .eq(User::getId, id);
        User one = this.getOne(queryWrapper);
        // 当查询字段本来就为null时, mybatis plus也会返回一个null, 不会封装成对象返回
        return one == null ? null : one.getName();
    }

    @Override
    public Map<Long, User> getByIds(Collection<Long> userIds) {
        if (userIds == null || userIds.isEmpty()) {
            return null;
        }
        return userMapper.getNameByIds(userIds);
    }

    @Override
    public long getFansCount(long userId) {
        LambdaQueryWrapper<Follow> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Follow::getUploader, userId);
        return followService.count(queryWrapper);
    }

    @Override
    public User getTelAndMailById(long userId) {
        return this.getOne(new LambdaQueryWrapper<User>()
                .select(User::getPhone, User::getEmail)
                .eq(User::getId, userId)
        );
    }
}
